package com.njym.java.security.app.biz;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.njym.java.annotation.Cache;
import com.njym.java.security.app.entity.Comment;
import com.njym.java.security.app.entity.CourseCatalogue;
import com.njym.java.security.app.entity.CourseCatalogueVo;
import com.njym.java.security.app.entity.CourseSection;
import com.njym.java.security.app.mapper.CourseCatalogueMapper;
import com.njym.java.security.app.utils.RedisUtils;
import com.njym.java.security.common.biz.BaseBiz;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @author Mr.AG
 * @email 463540703@qq.com
 * @date 2019-11-07 16:47:09
 */
@Service
public class CourseCatalogueBiz extends BaseBiz<CourseCatalogueMapper, CourseCatalogue> {
	@Autowired
	private CourseSectionBiz courseSectionBiz;

	@Autowired
	private TeacherBiz teacherBiz;

	@Autowired
	private CommentBiz commentBiz;

	@Autowired
	private RedisUtils redisUtil;

	private final static int CORE_POOL_SIZE = 3;

	/**
	 * 池中允许的最大线程数。
	 */
	private final static int MAXIMUM_POOL_SIZE = 10;

	/**
	 * 当线程数大于核心线程时，此为终止前多余的空闲线程等待新任务的最长时间1s
	 */
	private final static long KEEP_ALIVE_TIME = 1000;

	/**
	 * 执行前用于保持任务的队列，即任务缓存队列
	 */
	private final static ArrayBlockingQueue<Runnable> WORK_QUEUE = new ArrayBlockingQueue<>(2048);

	/**
	 * 拒绝策略，都满的情况下把被拒绝的线程重新执行
	 */
	private final static RejectedExecutionHandler HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();

	private static ThreadPoolExecutor executorService = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.MILLISECONDS, WORK_QUEUE, HANDLER);

	public List<CourseCatalogue> getCourse(Integer page,Integer size,Integer userId){
		PageHelper.startPage(page, size);
		return mapper.getCourse(userId);
	}

	@Cache(key = "getFreeCourses",expire = 2)
	public List<CourseCatalogue> getFreeCourses() {
		return mapper.getFreeCourses();
	}

	@Cache(key = "getCourses",expire = 2)
	public List<CourseCatalogueVo> getCourses() {
		return mapper.getCourses();
	}

//	@Cache(key = "getClassCount")
	public List<CourseCatalogueVo> getClassCount() {
		return mapper.getClassCount();
	}

//	@Cache(key = "getTenCourse")
	public List<CourseCatalogueVo> getTenCourse() {
		return mapper.getTenCourse();
	}

//	@Cache(key = "getCourseId:{1}")
	public Integer getCourseId(String courseName) {
		return mapper.getCourseId(courseName);
	}

	@Cache(key = "getAinengLife_free:{1}",expire = 2)
	public List<CourseCatalogue> getAinengLife_free(String classifyName) {
		return mapper.getAinengLife_free(classifyName);
	}

	@Cache(key = "getAinengLife_others:{1}",expire = 2)
	public List<CourseCatalogue> getAinengLife_others(String classifyName) {
		return mapper.getAinengLife_others(classifyName);
	}

	@Cache(key = "getZhangJin_recommend",expire = 2)
	public List<CourseCatalogue> getZhangJin_recommend() {
		return mapper.getZhangJin_recommend();
	}

	@Cache(key = "getFamilyEdu_free:{1}",expire = 2)
	public List<CourseCatalogue> getFamilyEdu_free(String classifyName) {
		return mapper.getFamilyEdu_free(classifyName);
	}

	@Cache(key = "getFamilyEdu_others:{1}",expire = 2)
	public List<CourseCatalogue> getFamilyEdu_others(String classifyName) {
		return mapper.getFamilyEdu_others(classifyName);
	}

//	@Cache(key = "AllSetionInfoByCourseId:{1}",expire = 5)
	public Map getSetionInfo(String couId,Integer page,Integer limit){
		// 获取课程信息
		FutureTask<CourseCatalogue> catalogueFutureTask = new FutureTask<>(() -> super.selectById(Integer.parseInt(couId)));
		//获取课时信息
		FutureTask<Map> sectionFutureTask = new FutureTask<>(() -> {
			Example example = new Example(CourseSection.class);
			example.createCriteria().andEqualTo("couId", Integer.parseInt(couId)).andEqualTo("deleted",0).andLessThan("showTime",new Date());
			example.orderBy("sectionOrder").desc();
			Map<String,Object> map = new HashMap<>(2);
			List<CourseSection> list = courseSectionBiz.selectByExample(example);
			list.forEach(CourseSection ->{
				// 获取每一篇文章在redis中的浏览量，存入到数据库中
				String key  = "id_"+CourseSection.getId();
				Long view = redisUtil.size(key);
				if(view>0){
					Long views = view + CourseSection.getPlayTimes();
					CourseSection.setPlayTimes(Math.toIntExact(views));
				}
			});
			map.put("total",list.size());
			map.put("content",list);
			return map;
		});
		//获取评论信息
		FutureTask<Map> commentFutureTask = new FutureTask<>(() -> {
			Example example = new Example(Comment.class);
			example.createCriteria().andEqualTo("courseId", Integer.parseInt(couId));
			example.orderBy("date").desc();
			Page<Object> result = PageHelper.startPage(page, limit);
			commentBiz.selectByExample(example);
			Map<String, Object> map = new HashMap<>(2);
			map.put("total", result.getTotal());
			map.put("content", result.getResult());
			return map;
		});
		executorService.submit(catalogueFutureTask);
		executorService.submit(sectionFutureTask);
		executorService.submit(commentFutureTask);

		Map<Object, Object> data = new HashMap<>(16);
		try {
			data.put("catalogue", catalogueFutureTask.get());
			data.put("section", sectionFutureTask.get());
			data.put("comment", commentFutureTask.get());
			Integer teacherId = catalogueFutureTask.get().getTeachers();
			data.put("teacher", teacherBiz.selectById(teacherId));
		}
		catch (InterruptedException e) {
			e.printStackTrace();
		}
		catch (ExecutionException e) {
			e.printStackTrace();
		}
		return data;
	}

    public void addCollects(Integer couId) {
		mapper.addCollects(couId);
    }

	public void addLikes(Integer couId) {
		mapper.addLikes(couId);
	}
}